import React, { useEffect, useRef, useState } from "react";
import {
  PanResponder,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from "react-native";

interface RotationRulerProps {
  value?: number; // 当前角度值
  minValue?: number; // 最小角度值，默认-45
  maxValue?: number; // 最大角度值，默认45
  step?: number; // 步长，默认1
  thumbColor?: string; // 指针颜色，默认"#222"
  activeThumbColor?: string; // 激活状态指针颜色，默认"#3B82F6"
  markColor?: string; // 刻度颜色，默认"#999"
  activeMark?: string; // 激活刻度颜色，默认"#3B82F6"
  onValueChange?: (value: number) => void; // 值变化回调
  onOffsetValueChange?: (value: number) => void; // currentOffset变化时的回调，传递计算后的数值
  style?: any; // 自定义样式
  animationDuration?: number; // 惯性动画执行时间，默认300
}

const RotationRuler: React.FC<RotationRulerProps> = ({
  value = 0.0,
  minValue = -45,
  maxValue = 45,
  step = 1,
  thumbColor = "#222",
  activeThumbColor = "#3B82F6",
  markColor = "#999",
  activeMark = "#3B82F6",
  onValueChange,
  onOffsetValueChange,
  style,
  animationDuration = 300,
}) => {
  // 状态声明
  const [containerWidth, setContainerWidth] = useState(0);
  const [currentOffset, setCurrentOffset] = useState(0);
  const [isAnimating, setIsAnimating] = useState(false);

  // 计算总刻度数和间距
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const totalMarks = Math.floor((maxValue - minValue) / step) + 1;
  const markSpacing = 8;
  const gapAndLineWidth = markSpacing; // 刻度间距
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const totalWidth = (maxValue - minValue) * gapAndLineWidth; // 总宽度

  // 边界偏移量 - 确保可以滑动到所有有效值
  // 当offset=0时显示0，向左滑动显示正值，向右滑动显示负值
  const maxOffset = Math.abs(maxValue) * gapAndLineWidth; // 最大正值对应的偏移
  const minOffset = Math.abs(minValue) * gapAndLineWidth; // 最大负值对应的偏移
  const leftOffset = -maxOffset; // 左边界（显示最大正值）
  const rightOffset = minOffset; // 右边界（显示最大负值）

  // 动画相关
  const animationFrameId = useRef<number | null>(null);
  const lastVibrateValue = useRef(0);
  const startX = useRef(0);
  const lastOffset = useRef(0);
  // 存储上一次滑动结束时的值
  const lastEndValue = useRef(0);

  // easeOutCubic 缓动函数
  const easeOutCubic = (t: number) => {
    return 1 - Math.pow(1 - t, 3);
  };

  // 根据偏移量计算当前值
  const calculateCurrentValue = React.useCallback(
    (offset: number) => {
      if (containerWidth === 0) return 0;
      // offset为0时对应0.0，向左滑动为正值，向右滑动为负值
      const currentValue = -offset / gapAndLineWidth;
      const clampedValue = Math.max(minValue, Math.min(maxValue, currentValue));

      return clampedValue;
    },
    [containerWidth, gapAndLineWidth, minValue, maxValue]
  );

  // 根据值计算目标偏移量
  const calculateTargetOffset = React.useCallback(
    (val: number) => {
      if (containerWidth === 0) return 0;
      // 0.0对应offset为0，正值向左偏移（负offset），负值向右偏移（正offset）
      const targetOffset = -val * gapAndLineWidth;
      return targetOffset;
    },
    [containerWidth, gapAndLineWidth]
  );

  // 跟踪上一次的外部value值，用于检测外部变化
  const lastExternalValue = useRef(value);
  const isUserInteracting = useRef(false);
  const isInitialized = useRef(false);
  // 跟踪当前实际的偏移值（用于解决状态更新异步问题）
  const currentOffsetRef = useRef(currentOffset);

  // 监听currentOffset变化，将计算值传递给外部
  useEffect(() => {
    if (onOffsetValueChange && containerWidth > 0) {
      const calculatedValue = calculateCurrentValue(currentOffset);
      const formattedValue = parseFloat(calculatedValue.toFixed(1));
      onOffsetValueChange(formattedValue);
    }
  }, [
    currentOffset,
    onOffsetValueChange,
    containerWidth,
    calculateCurrentValue,
  ]);

  // 初始化和响应外部value变化
  useEffect(() => {
    if (containerWidth > 0) {
      // 首次初始化
      if (!isInitialized.current) {
        const roundedValue = Math.round(value);
        const targetOffset = calculateTargetOffset(roundedValue);
        const clampedOffset = Math.max(
          leftOffset,
          Math.min(rightOffset, targetOffset)
        );
        setCurrentOffset(clampedOffset);
        currentOffsetRef.current = clampedOffset;
        lastExternalValue.current = value;
        // 初始化上一次结束值
        lastEndValue.current = roundedValue;
        isInitialized.current = true;
        return;
      }
      console.log(currentOffset, "currentOffset");
      // 禁用外部value变化的处理，组件内部维护自己的值
      // const isExternalChange = !isUserInteracting.current && lastExternalValue.current !== value;

      // if (isExternalChange) {
      //   // 外部value变化，更新位置
      //   const roundedValue = Math.round(value);
      //   const targetOffset = calculateTargetOffset(roundedValue);
      //   const clampedOffset = Math.max(leftOffset, Math.min(rightOffset, targetOffset));
      //   setCurrentOffset(clampedOffset);
      //   currentOffsetRef.current = clampedOffset;
      //   lastExternalValue.current = value;

      //   console.log('外部值变化:', {
      //     value,
      //     roundedValue,
      //     targetOffset,
      //     clampedOffset,
      //     isUserInteracting: isUserInteracting.current
      //   });
      // }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [containerWidth, value, leftOffset, rightOffset]);

  // 震动反馈函数
  const triggerVibration = () => {
    try {
      // 使用expo-haptics提供更好的震动反馈
      import("expo-haptics")
        .then(({ ImpactFeedbackStyle, impactAsync }) => {
          impactAsync(ImpactFeedbackStyle.Light);
        })
        .catch(() => {
          // 如果expo-haptics不可用，尝试使用原生震动
          try {
            if (
              typeof window !== "undefined" &&
              "navigator" in window &&
              "vibrate" in navigator
            ) {
              navigator.vibrate(10);
            }
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
          } catch (e) {
            // 忽略震动错误
          }
        });
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
    } catch (error) {
      // 忽略震动错误
    }
  };

  // 检查是否需要震动反馈
  const checkVibration = (currentValue: number) => {
    const roundedValue = Math.round(currentValue);
    // 只有当跨越整数刻度时才震动
    if (roundedValue !== lastVibrateValue.current) {
      triggerVibration();
      lastVibrateValue.current = roundedValue;
    }
  };

  // 处理值变化
  const handleValueChange = (newValue: number) => {
    const clampedValue = Math.max(minValue, Math.min(maxValue, newValue));

    // 更新最后的外部值引用
    lastExternalValue.current = clampedValue;

    if (onValueChange) {
      onValueChange(clampedValue);
    }
  };

  // 执行吸附逻辑
  const snapToNearestStep = (offsetOverride?: number) => {
    const actualCurrentOffset = offsetOverride ?? currentOffsetRef.current;
    const currentValue = calculateCurrentValue(actualCurrentOffset);

    // 检查是否需要吸附：只有当距离最近的整数刻度很近时才吸附
    const nearestIntegerValue = Math.round(currentValue);
    const valueDifference = Math.abs(currentValue - nearestIntegerValue);
    const shouldSnap = valueDifference <= 0.1; // 误差在0.1以内才吸附

    let finalValue = currentValue;
    let targetOffset = actualCurrentOffset;

    if (shouldSnap) {
      // 吸附到最近的整数刻度
      finalValue = nearestIntegerValue;
      targetOffset = calculateTargetOffset(finalValue);
      // 边界限制
      targetOffset = Math.max(leftOffset, Math.min(rightOffset, targetOffset));
    }

    console.log("吸附逻辑:", {
      currentValue,
      nearestIntegerValue,
      valueDifference,
      shouldSnap,
      finalValue,
      targetOffset,
      actualCurrentOffset,
      leftOffset,
      rightOffset,
    });

    if (shouldSnap && Math.abs(targetOffset - actualCurrentOffset) > 0.5) {
      // 需要吸附且距离足够远，启动吸附动画
      startInertialAnimation(targetOffset);
    } else {
      // 不需要吸附或已经很接近，直接设置最终值
      setCurrentOffset(targetOffset);
      currentOffsetRef.current = targetOffset;
      handleValueChange(finalValue);
    }
  };

  // 启动惯性动画
  const startInertialAnimation = (targetOffset: number) => {
    const startOffset = currentOffsetRef.current;
    const distance = targetOffset - startOffset;

    if (distance === 0) return;

    setIsAnimating(true);
    const startTime = Date.now();

    const animate = () => {
      const now = Date.now();
      const progress = Math.min((now - startTime) / animationDuration, 1);
      const easeProgress = easeOutCubic(progress);

      const newOffset = Math.round(startOffset + distance * easeProgress);
      setCurrentOffset(newOffset);
      currentOffsetRef.current = newOffset;

      if (progress < 1) {
        animationFrameId.current = requestAnimationFrame(animate);
      } else {
        setIsAnimating(false);
        // 确保最终位置精确
        setCurrentOffset(targetOffset);
        currentOffsetRef.current = targetOffset;
        const finalValue = calculateCurrentValue(targetOffset);
        handleValueChange(Math.round(finalValue));
      }
    };

    // 取消旧动画
    if (animationFrameId.current) {
      cancelAnimationFrame(animationFrameId.current);
    }

    // 执行新动画
    animate();
  };

  // 创建PanResponder
  const panResponder = useRef(
    PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onMoveShouldSetPanResponder: () => true,
      onPanResponderGrant: (evt: any) => {
        if (!isAnimating) {
          // 标记用户正在交互
          isUserInteracting.current = true;

          // 记录开始位置和当前偏移
          startX.current = evt.nativeEvent.pageX;
          lastOffset.current = currentOffsetRef.current; // 使用ref值确保准确性
        }
      },
      onPanResponderMove: (evt: any) => {
        if (!isAnimating) {
          // 计算滑动距离
          const deltaX = evt.nativeEvent.pageX - startX.current;
          let newOffset = Math.max(
            leftOffset,
            Math.min(rightOffset, lastOffset.current + deltaX)
          );

          // 滑动时的磁性吸附效果
          const currentValue = calculateCurrentValue(newOffset);
          const nearestValue = Math.round(currentValue);
          const nearestOffset = calculateTargetOffset(nearestValue);

          // 如果距离最近的整数刻度很近，就吸附过去
          const snapDistance = gapAndLineWidth * 0.2; // 减小吸附距离阈值，让吸附更精确
          if (Math.abs(newOffset - nearestOffset) < snapDistance) {
            newOffset = nearestOffset;
            // 吸附时触发震动反馈
            const finalValue = calculateCurrentValue(newOffset);
            checkVibration(finalValue);
          }

          setCurrentOffset(newOffset);
          currentOffsetRef.current = newOffset;

          // 计算最终值
          const finalValue = calculateCurrentValue(newOffset);

          // 检测震动反馈（只在非吸附状态下检测，避免重复震动）
          if (Math.abs(newOffset - nearestOffset) >= snapDistance) {
            checkVibration(finalValue);
          }

          // 实时更新值 - 滑动时实时回调
          handleValueChange(finalValue);
        }
      },
      onPanResponderRelease: () => {
        if (!isAnimating) {
          // 直接传递当前的偏移量给吸附函数，避免状态同步问题
          const actualCurrentOffset = currentOffsetRef.current;
          const currentValue = calculateCurrentValue(actualCurrentOffset);

          // 更新上一次滑动结束的值
          lastEndValue.current = Math.round(currentValue);

          // snapToNearestStep(actualCurrentOffset); // 暂时禁用吸附

          // 立即重置用户交互标志
          isUserInteracting.current = false;
        }
      },
      onPanResponderTerminate: () => {
        if (!isAnimating) {
          const actualCurrentOffset = currentOffsetRef.current;
          const currentValue = calculateCurrentValue(actualCurrentOffset);

          // 更新上一次滑动结束的值
          lastEndValue.current = Math.round(currentValue);

          snapToNearestStep(actualCurrentOffset);

          // 立即重置用户交互标志
          isUserInteracting.current = false;
        }
      },
    })
  ).current;

  // 生成刻度标记
  const renderMarks = () => {
    const marks = [];

    // 确保刻度从minValue到maxValue，每个都是整数
    const currentValue = calculateCurrentValue(currentOffset); // 当前实际值（可能是小数）
    const nearestValue = Math.round(currentValue); // 最接近的整数值

    for (let i = minValue; i <= maxValue; i += step) {
      const isLong = i % 15 === 0;
      const isMedium = i % 5 === 0;
      const isActive = i === nearestValue; // 激活最接近的整数刻度
      const isZero = i === 0; // 判断是否为0刻度
      marks.push(
        <View key={i} style={{ width: markSpacing, alignItems: "center", position: "relative"}} >
          {/* 0刻度上方的点标记 */}
          {isZero && <View style={styles.zeroMarker} />}
          <TouchableOpacity
            style={{ width: "100%", alignItems: "center" }}
            onPress={() => {
              const targetOffset = calculateTargetOffset(i);
              const clampedOffset = Math.max(
                leftOffset,
                Math.min(rightOffset, targetOffset)
              );
              setCurrentOffset(clampedOffset);
              handleValueChange(i);
            }}
            activeOpacity={0.6}
          >
            <View
              style={[
                styles.mark,
                { backgroundColor: markColor },
                isMedium && styles.markMedium,
                isLong && styles.markLong,
                isActive && { backgroundColor: activeMark },
                isZero && styles.markZero, // 0刻度特殊样式
              ]}
            />
          </TouchableOpacity>
        </View>
      );
    }
    return marks;
  };

  // 清理动画
  useEffect(() => {
    return () => {
      if (animationFrameId.current) {
        cancelAnimationFrame(animationFrameId.current);
      }
    };
  }, []);

  return (
    <View style={[styles.container, style]}>
      <View
        style={styles.marks}
        onLayout={(e) => {
          setContainerWidth(e.nativeEvent.layout.width);
        }}
        {...panResponder.panHandlers}
      >
        <View style={styles.marksWrapper}>
          <View style={styles.marksContainer}>
            <View
              style={[ styles.marksContent, { transform: [ { translateX: -(   Math.abs(minValue) * markSpacing +   markSpacing / 2 ),}, { translateX: currentOffset }]}]}>
              {renderMarks()}
            </View>
          </View>
        </View>
        <View style={[styles.thumb, { backgroundColor: thumbColor }]} />
      </View>

      {/* 指针下方显示当前值 */}
      <View style={styles.valueDisplay}>
        <Text style={styles.valueText}>
          {calculateCurrentValue(currentOffset).toFixed(1)}
        </Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    paddingVertical: 10,
    alignItems: "center",
    overflow: "hidden",
    marginHorizontal: 10,
  },
  marks: {
    flexDirection: "row",
    alignItems: "flex-start",
    height: 30,
    position: "relative",
    width: "100%",
    overflow: "hidden",
  },
  marksWrapper: {
    position: "absolute",
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    overflow: "hidden",
  },
  marksContainer: {
    position: "absolute",
    flexDirection: "row",
    alignItems: "flex-start",
    height: "100%",
    left: "50%",
  },
  marksContent: {
    flexDirection: "row",
    alignItems: "flex-start",
    height: "100%",
  },
  mark: {
    width: 1,
    height: 5,
  },
  markMedium: {
    height: 8,
    backgroundColor: "#666",
  },
  markLong: {
    height: 12,
    backgroundColor: "#333",
  },
  markZero: {
    height: 15,
    backgroundColor: "#3B82F6",
    width: 2,
  },
  markValue: {
    fontSize: 10,
    color: "#666",
    position: "absolute",
    top: 14,
    width: 30,
    textAlign: "center",
    left: -15,
  },
  thumb: {
    width: 2,
    height: 16,
    position: "absolute",
    left: "50%",
    marginLeft: -1, // 指针居中
    top: 0,
    zIndex: 10,
  },

  // 指针下方数值显示样式
  valueDisplay: {
    alignItems: "center",
  },
  valueText: {
    fontSize: 12,
    color: "#222",
  },
  // 0刻度上方的点标记
  zeroMarker: {
    width: 8,
    height: 8,
    borderRadius: 4,
    backgroundColor: "#FF0000", // 先用红色测试是否显示
    position: "absolute",
    top: -15,
    left: "50%",
    marginLeft: -4, // 居中：-width/2
    zIndex: 100,
  },
});

export default RotationRuler;
